package vip.aster.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.aster.framework.mybatis.enums.DataScopeEnum;
import vip.aster.common.constant.enums.SuperAdminEnum;
import vip.aster.common.utils.PageInfo;
import vip.aster.framework.security.entity.UserDetail;
import vip.aster.system.entity.SysRole;
import vip.aster.system.mapper.SysRoleMapper;
import vip.aster.system.query.SysRoleQuery;
import vip.aster.system.service.SysRoleMenuService;
import vip.aster.system.service.SysRoleOrgService;
import vip.aster.system.service.SysRoleService;
import vip.aster.system.service.SysUserRoleService;
import vip.aster.system.vo.SysRoleOrgVO;
import vip.aster.system.vo.SysRoleVO;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author Aster
 * @since 2023-11-28 10:36
 */
@Service
@AllArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
    private SysRoleMapper sysRoleMapper;
    private SysRoleMenuService sysRoleMenuService;
    private SysUserRoleService sysUserRoleService;
    private SysRoleOrgService sysRoleOrgService;

    @Override
    public String getDataScopeByUserId(String userId) {
        List<String> dataScopes = sysRoleMapper.getDataScopeByUserId(userId);
        if (CollUtil.isNotEmpty(dataScopes)) {
            List<Integer> list = dataScopes.stream().map(Integer::parseInt).sorted().toList();
            return String.valueOf(list.get(0));
        }
        return null;
    }

    @Override
    public PageInfo<SysRoleVO> pageList(SysRoleQuery query) {
        Page<SysRole> page = new Page<>(query.getPageNum(), query.getPageSize());
        Page<SysRole> rolePage = sysRoleMapper.selectPage(page, getWrapper(query));
        return new PageInfo<>(SysRoleVO.convertList(rolePage.getRecords()), rolePage.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SysRoleVO vo) {
        SysRole role = new SysRole();
        BeanUtil.copyProperties(vo, role, true);

        if (StrUtil.isNotBlank(role.getId())) {
            // 更新角色表
            this.updateById(role);
            // 更新角色菜单表
            sysRoleMenuService.saveByRoleId(role.getId(), vo.getMenuIdList());
        } else {
            // 插入角色表
            sysRoleMapper.insert(role);
            // 插入角色菜单表
            sysRoleMenuService.saveByRoleId(role.getId(), vo.getMenuIdList());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<String> idList) {
        // 删除角色
        this.removeBatchByIds(idList);

        // 删除用户角色关系
        sysUserRoleService.deleteByRoleIdList(idList);

        // 删除角色菜单关系
        sysRoleMenuService.deleteByRoleIdList(idList);

        // 删除角色机构关系
        sysRoleOrgService.deleteByRoleIdList(idList);
    }

    @Override
    public void updateOrg(SysRoleOrgVO roleOrg) {
        SysRole role = this.getById(roleOrg.getId());
        role.setDataScope(roleOrg.getDataScope());
        // 更新角色
        this.updateById(role);
        // 更新角色机构关系
        if (DataScopeEnum.CUSTOM.getValue().equals(roleOrg.getDataScope())) {
            sysRoleOrgService.save(role.getId(), roleOrg.getOrgIdList());
        } else {
            sysRoleOrgService.deleteByRoleIdList(ListUtil.toList(role.getId()));
        }
    }

    @Override
    public Set<String> getRoleCode(UserDetail user) {
        List<String> roleCodeList;
        if (SuperAdminEnum.YES.getValue().equals(user.getSuperAdmin())) {
            roleCodeList = this.list(getWrapper(new SysRoleQuery())).stream().map(SysRole::getRoleCode).toList();
        } else {
            roleCodeList = sysRoleMapper.getUserRoleCode(user.getId());
        }
        // 用户权限列表
        Set<String> roleCodeSet = new HashSet<>();
        for (String roleCode : roleCodeList) {
            if (StrUtil.isBlank(roleCode)) {
                continue;
            }
            roleCodeSet.addAll(Arrays.asList(roleCode.trim().split(",")));
        }
        return roleCodeSet;

    }

    private LambdaQueryWrapper<SysRole> getWrapper(SysRoleQuery query) {
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(query.getRoleName()), SysRole::getRoleName, query.getRoleName());
        queryWrapper.like(StrUtil.isNotBlank(query.getRoleCode()), SysRole::getRoleCode, query.getRoleCode());
        queryWrapper.eq(StrUtil.isNotBlank(query.getStatus()), SysRole::getStatus, query.getStatus());
        queryWrapper.orderByAsc(SysRole::getSort);
        return queryWrapper;
    }
}
